package web

import (
	"encoding/json"
	"fmt"
	"gitee.com/pdudo/SampleDNS2/db"
	"log"
	"net/http"
	"strings"
	"time"
	_ "gitee.com/pdudo/SampleDNS2/log"
)

const GOTIMEFORMAT string = "2006-01-02 15:04"

func Web() {
	http.Handle("/", http.FileServer(assetFS()))
	http.HandleFunc("/data",webIndex) // 数据查看
	http.HandleFunc("/add",AddIndex) // 新增记录
	http.HandleFunc("/del",DelIndex) // 删除记录
	http.HandleFunc("/update",UpdateIndex) // 更新记录
	http.HandleFunc("/flush",FlushIndex) // 清理缓存 status
	http.HandleFunc("/status",UpdateStatus) // 开始/暂停解析
	http.HandleFunc("/findOne",FindOne) // 查询单个记录
	log.Println("Web Server Start " , db.DnsConf.ConfWeb.Bind)
	log.Fatal(http.ListenAndServe(db.DnsConf.ConfWeb.Bind,nil)) // 监听

}

func controlAllowOriginAll(w http.ResponseWriter) {
	w.Header().Set("Access-Control-Allow-Origin","*")
}

func httpMethodAllow(w http.ResponseWriter,r *http.Request) {
	if "POST" != r.Method {
		log.Println(r.RemoteAddr + " Method error " + r.Method)
		w.Write([]byte(r.RemoteAddr + " Method error " + r.Method))
		return
	}
}

func FindOne(w http.ResponseWriter,r *http.Request) {
	controlAllowOriginAll(w)

	httpMethodAllow(w,r)

	postFormDomanName := r.PostFormValue("DomanName")
	postFormServerKeys := r.PostFormValue("ServerKeys")

	domanServers := strings.SplitN(postFormDomanName,".",2)[1]

	domanHost := postFormServerKeys
	domanServer := fmt.Sprintf("%s_%s",db.DnsConf.ConfWeb.RegisterKeys , domanServers)

	var rs returnData

	result , err := db.HGet(domanServer,domanHost)
	if err != nil {
		rs.Code = -1
		rs.Msg = "查询失败"
	} else {
		rs.Code = 0
		rs.Msg = "查询成功"

		//var sInfo []showDNSInfo
		sInfo := make([]showDNSInfo,1)
		sInfo[0].ServerKeys = domanHost

		err = json.Unmarshal([]byte(result),&sInfo[0])
		if err != nil {
			log.Println(err)
		}
		rs.Data = sInfo
	}

	buf , _ := json.Marshal(rs)
	w.Write(buf)
}

func UpdateStatus(w http.ResponseWriter,r *http.Request) {
	controlAllowOriginAll(w)

	httpMethodAllow(w,r)
	//
	postFormDomanName := r.PostFormValue("DomainName")
	postFormServerKeys := r.PostFormValue("ServerKeys")
	postFormType := r.PostFormValue("Type")

	domanHosts := strings.SplitN(postFormDomanName,".",2)[0]
	domanServers := strings.SplitN(postFormDomanName,".",2)[1]

	domanHost := fmt.Sprintf("%s_%s",domanHosts,postFormType)
	domanServer := fmt.Sprintf("%s_%s",db.DnsConf.ConfWeb.RegisterKeys , domanServers)


	// 暂停当前解析(如果有)
	oldValue , err  := db.HGet(domanServer,domanHost)
	if err == nil {
		newKey := fmt.Sprintf("%s%v",domanHost,time.Now().Unix())
		db.HSet(domanServer,newKey,oldValue)
		db.HDel(domanServer,domanHost)
	}

	var rs returnData
	// 启用解析
	if !strings.HasSuffix(postFormServerKeys,"_A") && !strings.HasSuffix(postFormServerKeys,"_CNAME") {
		newValue , err := db.HGet(domanServer,postFormServerKeys)
		if err != nil {
			log.Println("ghet " , domanServer , postFormServerKeys , "error " , err)
			rs.Code = -1
			rs.Msg = "状态修改失败"
			buf , _ := json.Marshal(rs)
			w.Write(buf)
			return
		}
		db.HSet(domanServer,domanHost,newValue)
		db.HDel(domanServer,postFormServerKeys)
	}

	rs.Code = 0
	rs.Msg = "状态修改成功"
	buf , _ := json.Marshal(rs)
	w.Write(buf)
}

func FlushIndex(w http.ResponseWriter,r *http.Request) {
	//w.Header().Set("Access-Control-Allow-Origin","*")
	controlAllowOriginAll(w)

	httpMethodAllow(w,r)

	var cursor uint64
	var rs returnData

	keys , err := db.Scan(cursor,"dnsCache*",10)
	if err != nil {
		log.Println(r.RemoteAddr , " flushIndex scan redis error " , err)

		rs.Code = -1
		buf , _ := json.Marshal(rs)
		w.Write(buf)

		log.Println(r.RemoteAddr , " PostForm" , r.URL  , " returnData" , rs)
		return
	}

	for _,v := range keys {
		log.Println(r.RemoteAddr ,"delete cache redis key" , v)
		_ ,err = db.Del(v)
		if err != nil {
			log.Println(r.RemoteAddr ,"delete cache redis keys " , v , " error " , err)
			break
		}
	}

	rs.Code = 0
	buf , _ := json.Marshal(rs)
	log.Println(r.RemoteAddr , " PostForm" , r.URL  , " returnData" , rs)
	w.Write(buf)
}

func UpdateIndex(w http.ResponseWriter,r *http.Request) {
	//w.Header().Set("Access-Control-Allow-Origin","*")
	controlAllowOriginAll(w)

	httpMethodAllow(w,r)

	postFormDomanName := r.PostFormValue("DomanName")
	postFormIP := r.PostFormValue("IP")
	postFormRemark :=  r.PostFormValue("Remark")
	postFormServerKeys := r.PostFormValue("ServerKeys")

	domanServers := strings.SplitN(postFormDomanName,".",2)[1]

	domanServer := fmt.Sprintf("%s_%s",db.DnsConf.ConfWeb.RegisterKeys , domanServers)

	var rs returnData

	if db.HExistsVal(domanServer,postFormServerKeys) {
		rst , err := db.HGet(domanServer,postFormServerKeys)
		if err != nil {
			log.Println(r.RemoteAddr,"Redis HGet  " , postFormDomanName ,err)
		}

		var saveinfo DnsSaveInfo
		err = json.Unmarshal([]byte(rst),&saveinfo)
		if err != nil {
			log.Println(r.RemoteAddr,"Unmarshal json " , rst ,err)
		}

		saveinfo.Ip = postFormIP
		saveinfo.Remark = postFormRemark
		saveinfo.UpdateTime = time.Unix(time.Now().Unix(),0).Format(GOTIMEFORMAT)

		save , _ := json.Marshal(saveinfo)
		db.HSet(domanServer,postFormServerKeys,save)

		rs.Code = 0
		rs.Msg = "存储成功"
		log.Println(r.RemoteAddr , " PostForm" , r.URL , "DomanName: " , postFormDomanName , " IP:" , postFormIP , " Remark:" , postFormRemark, " returnData" , rs)

		buf , _ := json.Marshal(rs)
		w.Write(buf)

		return
	}

	rs.Code = -1
	rs.Msg = "存储失败"
	log.Println(r.RemoteAddr , " PostForm" , r.URL , "DomanName: " , postFormDomanName  , " IP:" , postFormIP , " Remark:" , postFormRemark, " returnData" , rs)

	buf , _ := json.Marshal(rs)
	w.Write(buf)
}

func DelIndex (w http.ResponseWriter,r *http.Request) {
	//w.Header().Set("Access-Control-Allow-Origin","*")
	controlAllowOriginAll(w)
	httpMethodAllow(w,r)

	postFormDomanName := r.PostFormValue("DomainName")
	postFormServerKeys := r.PostFormValue("ServerKeys")

	if len(strings.SplitN(postFormDomanName,".",2)) < 2 {
		var rs returnData
		rs.Code = -1
		rs.Msg = "删除失败"

		log.Println(r.RemoteAddr , " PostForm" , r.URL , "DomanName: " , postFormDomanName , " Error : SplitN < 2")

		buf , _ := json.Marshal(rs)
		w.Write(buf)
		return
	}

	domanServers := strings.SplitN(postFormDomanName,".",2)[1]

	domanServer := fmt.Sprintf("%s_%s",db.DnsConf.ConfWeb.RegisterKeys , domanServers)


	_,err := db.HDel(domanServer,postFormServerKeys)
	if err != nil {
		var rs returnData
		rs.Code = -1
		rs.Msg = "删除失败"

		log.Println(r.RemoteAddr , " PostForm" , r.URL , "DomanName: " , postFormDomanName," returnData" , rs)
		buf , _ := json.Marshal(rs)
		w.Write(buf)
		return
	}
	var rs returnData
	rs.Code = 0
	rs.Msg = "删除成功"
	log.Println(r.RemoteAddr , " PostForm" , r.URL , "DomanName: " , postFormDomanName," returnData" , rs)

	buf , _ := json.Marshal(rs)
	w.Write(buf)
}

func AddIndex(w http.ResponseWriter,r *http.Request) {
	//w.Header().Set("Access-Control-Allow-Origin","*")
	controlAllowOriginAll(w)

	httpMethodAllow(w,r)

	postFormDomanName := r.PostFormValue("DomanName")
	postFormType := r.PostFormValue("Type")
	postFormIP := r.PostFormValue("IP")
	postFormRemark :=  r.PostFormValue("Remark")

	if !strings.HasSuffix(postFormDomanName,".") {
		postFormDomanName += "."
	}

	var rs returnData
	if "" == postFormDomanName {
		rs.Code = -1
		rs.Msg = "存储失败"

		log.Println(r.RemoteAddr , " PostForm" , r.URL , "DomanName: " , postFormDomanName , " Type: " , postFormType , " IP:" , postFormIP , " Remark:" , postFormRemark, " returnData" , rs)

		buf , _ := json.Marshal(rs)
		w.Write(buf)
		return
	}

	records := strings.SplitN(postFormDomanName,".",2)
	var domanServers string
	if "" == records[1] {
		domanServers = "root"
	} else {
		domanServers = records[1]
	}


	domanHosts := strings.SplitN(postFormDomanName,".",2)[0]

	domanHost := fmt.Sprintf("%s_%s",domanHosts,postFormType)
	domanServer := fmt.Sprintf("%s_%s",db.DnsConf.ConfWeb.RegisterKeys , domanServers)

	var saveinfo DnsSaveInfo
	saveinfo.ID = 0
	saveinfo.DomainName = postFormDomanName
	saveinfo.Ip = postFormIP
	saveinfo.Type = postFormType
	saveinfo.Remark = postFormRemark
	saveinfo.CreateTime = time.Unix(time.Now().Unix(),0).Format(GOTIMEFORMAT)
	saveinfo.UpdateTime = time.Unix(time.Now().Unix(),0).Format(GOTIMEFORMAT)

	saveinfoBuf , _ := json.Marshal(saveinfo)
	isok , _ :=db.HSet(domanServer,domanHost,saveinfoBuf)


	if isok {
		rs.Code = 0
		rs.Msg = "存储成功"

		log.Println(r.RemoteAddr , " PostForm" , r.URL , "DomanName: " , postFormDomanName , " Type: " , postFormType , " IP:" , postFormIP , " Remark:" , postFormRemark, " returnData" , rs)

		buf , _ := json.Marshal(rs)
		w.Write(buf)
		return
	}


	rs.Code = -1
	rs.Msg = "存储失败"

	log.Println(r.RemoteAddr , " PostForm" , r.URL , "DomanName: " , postFormDomanName , " Type: " , postFormType , " IP:" , postFormIP , " Remark:" , postFormRemark, " returnData" , rs)

	buf , _ := json.Marshal(rs)
	w.Write(buf)
}

func webIndex(w http.ResponseWriter,r *http.Request) {
	controlAllowOriginAll(w)

	httpMethodAllow(w,r)

	dnsMap,err := db.Scan(0,db.DnsConf.ConfWeb.RegisterKeys+"*",10)


	var inn []showDNSInfo
	var id int = 1

	if err == nil {
		for _,v := range dnsMap {

			nameMap , err := db.HGetAll(v)
			for k1,v1 := range nameMap {
				var saveinfo DnsSaveInfo

				err = json.Unmarshal([]byte(v1),&saveinfo)
				if err != nil {
					log.Println("dns 记录转json 解析失败 " , v)
				}

				var in showDNSInfo

				in.DomainName = saveinfo.DomainName
				in.ServerKeys = k1
				in.Ip = saveinfo.Ip
				in.ID = id
				in.Type = saveinfo.Type
				in.CreateTime = saveinfo.CreateTime
				in.UpdateTime = saveinfo.UpdateTime
				in.Remark = saveinfo.Remark
				if strings.HasSuffix(k1,"_A") || strings.HasSuffix(k1,"_CNAME") {
					in.Status = "正常解析"
				} else {
					in.Status = "暂停解析"
				}

				inn = append(inn, in)
				id++
			}
		}
		var rs returnData
		rs.Code = 0
		rs.Data = inn

		log.Println(r.RemoteAddr , " " , r.URL , " returnData" , rs)

		b , _ := json.Marshal(rs)

		w.Write(b)
		return
	}

	var rs returnData
	rs.Code = -1
	rs.Msg = "查询失败"
	log.Println(r.RemoteAddr , " " , r.URL , " returnData" , rs)

	b , _ := json.Marshal(rs)
	w.Write(b)
}